package com.ghy.component;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.json.JSONUtil;
import com.ghy.dto.RequestLogDTO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;


import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;


/**
 * @author GaoHeYang
 */
@Slf4j
@Aspect
@Component
public class ControllerAspect {
    @Around("execution(public * com.ghy.controller.*.*(..))")
    @SneakyThrows
    public Object aroundAdvice(ProceedingJoinPoint pjp) {
        //获取请求对象
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(
                RequestContextHolder.getRequestAttributes())).getRequest();
        //构建控制器日志DTO实体：包含本次请求的日志信息
        RequestLogDTO requestLogDTO = new RequestLogDTO();
        //开启计时器
        TimeInterval timer = DateUtil.timer(true);
        //执行控制方法
        Object result = pjp.proceed(pjp.getArgs());
        //停止计时器，获得总耗时
        requestLogDTO.setSpendTime(timer.intervalPretty());
        //设置请求URL，请求方式，请求地址，类名，方法名，参数，响应数据等
        requestLogDTO.setUrl(request.getRequestURL().toString());
        requestLogDTO.setRequestMethod(request.getMethod());
        requestLogDTO.setClassName(pjp.getSignature().getDeclaringTypeName());
        requestLogDTO.setMethodName(pjp.getSignature().getName());
        requestLogDTO.setParameters(JSONUtil.toJsonStr(pjp.getArgs()));
        requestLogDTO.setResponseData(JSONUtil.toJsonStr(result));
        log.info(requestLogDTO.toString());
        return result;
    }
}
